#version 450 compatibility








layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

layout(binding = 1, offset = 0) uniform atomic_uint m_PickCount;

layout(binding = 2) uniform Buf_GlobalParameter1 {
    mat4 m_ModelMatrix;
};
layout(binding = 3) uniform Buf_GlobalParameter2 {
    vec4 m_RaysNear;
    vec4 m_RaysFar;

    uvec2 m_Range;
};

layout(std430, binding = 5) buffer Buf_GlobalParameter4 {
    vec4 m_Vert[];
};
layout(std430, binding = 6) buffer Buf_GlobalParameter5 {
    uint m_Index[];
};
layout(std430, binding = 7) buffer Buf_GlobalParameter6 {
    vec4 m_Pick[];
};



void main() {
    uint id = gl_NumWorkGroups.x*gl_WorkGroupID.y + gl_WorkGroupID.x;

    //m_Pick[id] = vec4(55.66, 77.33, 99.11, 0.123456);
    id *= 3;
    if(id < m_Range.y) {
        id += m_Range.x;

        //atomicCounterIncrement(m_PickCount);
        vec4 v1 = (m_ModelMatrix * vec4(m_Vert[m_Index[id]].xyz, 1.0));
        vec4 v2 = (m_ModelMatrix * vec4(m_Vert[m_Index[id+1]].xyz, 1.0));
        vec4 v3 = (m_ModelMatrix * vec4(m_Vert[m_Index[id+2]].xyz, 1.0));
        
        vec3 near = m_RaysNear.xyz;
        vec3 far = m_RaysFar.xyz;


        vec3 edge1 = v2.xyz - v1.xyz;
        vec3 edge2 = v3.xyz - v1.xyz;

        //计算射线方向
        vec3 dir = normalize(far - near);
        
        //叉积计算
        vec3 pvec = cross(dir, edge2);
        float det = dot(edge1, pvec);

        vec3 tvec;
        //判断是否正面穿过
        if ( det > 0.0f )  {
            tvec = near - v1.xyz;
        }
        else {
            tvec = v1.xyz - near;
            det = -det ;
        }
        if( abs(det) < 0.000000001f ) return;

        
        vec4 uvt = vec4(1.0,1.0,1.0,1.0);
        //u
        uvt.x = dot(tvec, pvec);
        if( uvt.x < 0.0f || uvt.x > det ) return;
        vec3 qvec = cross(tvec, edge1);
        //atomicCounterIncrement(m_PickCount);
        //v
        uvt.y = dot(dir, qvec);
        if( uvt.y < 0.0f || (uvt.x + uvt.y) > det ) return;
        //t
        uvt.z = dot(edge2, qvec);
        float fInvDet = 1.0f / det;
        uvt *= fInvDet;
        
        uint count = atomicCounterIncrement(m_PickCount);

        edge1 *= uvt.x;
        edge2 *= uvt.y;
        m_Pick[count].xyz = v1.xyz + edge1;
        m_Pick[count].xyz += edge2;
        //m_Pick[count].xyz -= near;
        //m_Pick[count] = m_ModelMatrix * vec4(0.0, 0.0, uvt.z, 1.0);
        
    }

}





